﻿<template>
	<div class="card">
		<el-card>
			<div class="ard">
				<div class="asd">
					<p>编码</p>
					<el-input v-model="input" style="width: 240px" placeholder="请输入内容" />
				</div>
				<div class="asd">
					<p>类型</p>
					<el-select v-model="typeValue" class="m-2" placeholder="Select" style="width: 240px">
						<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
					</el-select>
				</div>
				<div class="asd">
					<p>状态</p>
					<el-select v-model="statusValue" class="m-2" placeholder="Select" style="width: 240px">
						<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
					</el-select>
				</div>
				<div class="asd">
					<p>产线</p>
					<el-select v-model="productionLineValue" class="m-2" placeholder="Select" style="width: 240px">
						<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
					</el-select>
				</div>
				<el-button style="margin-left: 10px" type="primary" :icon="Filter" @click="handleQuery">筛选</el-button>
				<el-button type="primary" :icon="Plus" @click="resetQuery">重置</el-button>
			</div>
		</el-card>
		<el-card class="box-card">
			<div id="gantt_here" style="margin-top: 10px" class="gantt-container"></div>
		</el-card>
	</div>
</template>

<script setup>
import { reactive, toRefs, ref, onBeforeMount, onMounted, watchEffect, defineExpose } from 'vue';
import { gantt } from 'dhtmlx-gantt';
import 'dhtmlx-gantt/codebase/dhtmlxgantt.css';
import { Plus, Filter } from '@element-plus/icons-vue';
import { useticketsApi } from '/@/api/ticket/tickets';
import dayjs from 'dayjs';

const ticketsApi = useticketsApi(); // 获取数据
const data = reactive({});
const radio1 = ref('年');
const radio2 = ref('全部');
const input = ref('');
const typeValue = ref('');
const statusValue = ref('');
const productionLineValue = ref('');
let objs = reactive({
	asd1: '#f2e6c2',
	asd2: '#b5e09b',
	asd3: '#baefe2',
});
let dialogVisible = ref(false);

const options = [
	{ value: 'option1', label: '选项1' },
	{ value: 'option2', label: '选项2' },
	// 可以根据实际情况添加更多选项
];

const state = reactive({
	exportLoading: false,
	tableLoading: false,
	stores: {},
	showAdvanceQueryUI: false,
	dropdownData: {},
	selectData: [],
	tableQueryParams: {},
	tableParams: {
		page: 1,
		pageSize: 20,
		total: 0,
		field: 'createTime', // 默认的排序字段
		order: 'descending', // 排序方向
		descStr: 'descending', // 降序排序的关键字符
	},
	tableData: [],
});

// 查询操作
const handleQuery = async (params = {}) => {
	state.tableLoading = true;

	try {
		const queryParams = {
			...state.tableQueryParams,
			...state.tableParams,
			...params,
			input: input.value,
			type: typeValue.value,
			status: statusValue.value,
			productionLine: productionLineValue.value,
		};

		const result = await ticketsApi.page(queryParams).then((res) => res.data.result);
		state.tableParams.total = result?.total;
		state.tableData = result?.items ?? [];
	} catch (error) {
		console.error('查询出错:', error);
	} finally {
		state.tableLoading = false;
		console.log('查询完成', state.tableData);
	}
};

// 重置查询
const resetQuery = () => {
	input.value = '';
	typeValue.value = '';
	statusValue.value = '';
	productionLineValue.value = '';
	handleQuery();
};

// 初始化甘特图的函数
const initGantt = () => {
	// 定义甘特图的任务数据对象，包含任务列表和任务链接列表
	var tasks = {
		// 使用 state.tableData 数组中的每一项来创建甘特图的任务数据
		data: state.tableData.map((item, index) => {
			// 计算持续时间（单位：毫秒）
			const durationInMs = dayjs(item.planEndtime).valueOf() - dayjs(item.planstarttime).valueOf();
			// 将持续时间转换为天并取整
			const ONE_DAY_IN_MS = 24 * 60 * 60 * 1000;
			let durationInDays = Math.round(durationInMs / ONE_DAY_IN_MS);

			return {
				// 任务的唯一标识符，使用数据项中的 id 字段
				id: item.id,
				// 任务的名称，使用数据项中的 encode 字段
				taskname: item.remark,
				// 父任务的 ID，0 表示没有父任务
				parent: 0,
				// 任务的开始日期，使用 dayjs 格式化数据项中的 planstarttime 字段为 'DD-MM-YYYY' 格式
				start_date: dayjs(item.planstarttime).format('DD-MM-YYYY'),
				// 任务的完成进度，将数据项中的 progress 字段（带 % 的字符串）转换为 0 到 1 之间的小数
				progress: parseFloat(item.progress.replace('%', '')) / 100,
				// 任务的持续时间，以天为单位
				duration: durationInDays,
				// 任务的类型，根据索引值对 3 取余再加 1 来确定，范围是 1 到 3
				types: item.ticketstype == '正常' ? 1 : item.ticketstype == '委外' ? 2 : 3,
				// 任务的相关文本信息，使用数据项中的 createUserName 字段
				text: item.remark,
				// 任务条的颜色，根据索引值对 3 取余的结果来选择不同的颜色
				color: index % 3 === 0 ? objs.asd1 : index % 3 === 1 ? objs.asd2 : objs.asd3,
				// 任务的优先级，根据索引值对 3 取余的结果来确定，范围是 0 到 2
				tsakrank: index % 3,
			};
		}),
	};
	console.log('tasks', tasks);

	// 设置甘特图网格的宽度
	gantt.config.grid_width = 400;
	// 禁用添加列的符号
	gantt.config.add_column = false;
	// 开启甘特图的自适应尺寸功能
	gantt.config.autosize = true;
	// 开启表格列宽自适应功能
	gantt.config.autofit = true;
	// 开启自动滚动功能，当任务或连线被拖拽到浏览器屏幕外时触发
	gantt.config.autoscroll = true;
	// 禁用任务进度条的拖动功能
	gantt.config.drag_progress = false;
	// 设置时间刻度的高度
	gantt.config.scale_height = 60;
	// 设置甘特图每行的高度
	gantt.config.row_height = 60;
	// 设置任务条的高度
	gantt.config.bar_height = 34;
	// 自动延长时间刻度以适应所有显示的任务
	gantt.config.fit_tasks = true;
	// 自动转换任务类型，包含子任务的任务转换为项目，无
	// 子任务的项目转换回任务
	gantt.config.auto_types = true;
	// 设置甘特图的语言为中文
	gantt.i18n.setLocale('cn');

	// 时间栏配置
	gantt.config.scales = [
		// 第一个时间刻度，以月为单位，每个刻度间隔1个月，格式为“年-月”
		{ unit: 'month', step: 1, format: '%Y年%m月' },
		// 第二个时间刻度，以天为单位，每个刻度间隔1天
		{
			unit: 'day',
			step: 1,
			format: function (date) {
				// 定义星期数组
				const weekdays = ['星期天', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
				// 返回格式化后的日期和星期信息，用 <br> 标签换行
				return `${gantt.date.date_to_str('%m/%d')(date)}<br>${weekdays[date.getDay()]}`;
			},
		},
	];
	// 左侧列表配置
	gantt.config.columns = [
		{
			// 列的名称
			name: 'taskname',
			// 列的标签显示文本
			label: '任务名称',
			// 文本对齐方式
			align: 'left',
			// 是否以树形结构显示
			tree: true,
			// 列的宽度
			width: 140,
		},
		{
			name: 'progress',
			label: '任务优先',
			align: 'center',
			width: 80,
			template: function (task) {
				// 根据任务的优先级设置颜色和图标
				let obj = {
					color: task.tsakrank === 0 ? '#ff2b00' : task.tsakrank === 1 ? '#ffab00' : '#409eff',
					icon: task.tsakrank === 0 ? 'icon-youxianjiP0' : task.tsakrank === 1 ? 'icon-youxianjiP1' : 'icon-youxianjiP2',
				};
				// 返回格式化后的HTML字符串
				return `<div class="jindu" style="color:${obj.color};"><i style="font-size:24px;" class="iconfont ${obj.icon}"></i></div>`;
			},
		},
		{
			name: 'type',
			label: '任务类别',
			align: 'center',
			width: 100,
			template: function (task) {
				// 根据任务的类型设置颜色、图标和文本
				let obj = {
					color: task.types === 1 ? '#f29d38' : task.types === 2 ? '#65c16f' : '#1890ff',
					icon: task.types === 1 ? 'icon-gongji' : task.types === 2 ? 'icon-kaiqifangyu' : 'icon-icon--mubiaoku',
					text: task.types === 1 ? '正常' : task.types === 2 ? '委外' : '维修',
				};
				// 返回格式化后的HTML字符串
				return `<div class="tasktype" style="color:${obj.color};font-size:14px;">
                    <i class="iconfont ${obj.icon}"></i>
                    <span style="margin-left:3px;"> ${obj.text}</span>
                    </div>`;
			},
		},
		{
			name: 'progress',
			label: '任务进度',
			align: 'center',
			width: 80,
			template: function (task) {
				// 返回任务进度的百分比字符串
				return `<div class="jindu" style="width:100%;height:30px;padding-left:10px;font-size:13px;color:black;"><span>${(task.progress * 100).toFixed(0) + '%'}</span></div>`;
			},
		},
	];

	// 更改父项图标，这里返回空字符串表示不显示默认图标
	gantt.templates.grid_folder = (item) => {
		return '';
	};

	// 启用甘特图的标记插件
	gantt.plugins({
		marker: true,
	});

	// 获取日期格式化函数
	var date_to_str = gantt.date.date_to_str(gantt.config.task_date);
	// 获取当前日期
	var today = new Date();
	// 在甘特图上添加一个标记，表示今天的日期
	gantt.addMarker({
		start_date: today,
		css: 'today',
		text: '今天',
		title: '今天: ' + date_to_str(today),
	});

	// 更改子项图标，这里返回空字符串表示不显示默认图标
	gantt.templates.grid_file = (item) => {
		return '';
	};

	// 任务条显示内容的模板函数
	gantt.templates.task_text = function (start, end, task) {
		return `
            <div style="color:#454545;font-size:14px;font-weight:700;">执行：${task.text}</div>
        `;
	};

	// 展开树图标
	gantt.templates.grid_open = function (item) {
		return `<i style="font-size:14px;background:none; color:#1890ff; padding-left:10px;" class="gantt_tree_icon gantt_${item.$open ? 'close' : 'open'}  iconfont  ${
			item.$open ? 'icon-zhankaishousuo' : 'icon-zhankaishousuo1'
		}"></i>`;
	};

	// 初始化甘特图，指定渲染的DOM元素ID
	gantt.init('gantt_here');
	// 将任务数据填充到甘特图中
	gantt.parse(tasks);

	// 绑定任务双击事件
	gantt.attachEvent('onTaskDblClick', function (id, e) {
		// 打印双击的任务ID
		console.log('双击了任务：' + id);
		// 显示对话框
		dialogVisible.value = true;
	});
};

onBeforeMount(() => {});
onMounted(() => {
	handleQuery();
	setTimeout(() => {
		initGantt();
	}, 1000);
});
watchEffect(() => {});
defineExpose({
	...toRefs(data),
});
</script>
<style scoped lang="scss">
::-webkit-scrollbar {
	width: 10px;
}

::-webkit-scrollbar-track {
	background-color: #f1f1f1;
}

::-webkit-scrollbar-thumb {
	background-color: #888;
	border-radius: 5px;
}

::-webkit-scrollbar-thumb:hover {
	background-color: #555;
}

.renwus {
	width: 100%;
	height: 200px;
	display: flex;
	align-items: center;
	justify-content: space-around;
	flex-wrap: wrap;
	overflow: auto;
}

.renwu {
	width: 100%;
	height: 200px;
	display: flex;
	align-items: center;
	justify-content: space-around;
	flex-wrap: wrap;
}

:deep(.el-progress-circle) {
	width: 100px !important;
	height: 80px !important;
}

.ps {
	padding: 0;
	margin: 0;
}

.percentage-value {
	display: block;
	margin-top: 10px;
	font-size: 28px;
}

.percentage-label {
	display: block;
	margin-top: 10px;
	font-size: 12px;
}

.demo-progress .el-progress--line {
	margin-bottom: 15px;
	width: 350px;
}

.demo-progress .el-progress--circle {
	margin-right: 15px;
}

.cardtop {
	width: 100%;
	height: 100%;
	display: flex;
	justify-content: space-between;
	align-items: center;

	.margins {
		display: flex;
		font-size: 12px;

		p {
			margin-left: 10px;

			:deep(.el-color-picker .el-color-picker__icon) {
				opacity: 0;
			}

			:deep(.el-color-picker__trigger) {
				border: none;
				width: 25px;
				height: 25px;
			}
		}
	}
}

.box-card {
	margin-top: 20px;
}

.card {
	width: 1500px;
	height: 1000px;
	margin: 0 auto;

	.ard {
		width: 100%;
		height: 40px;
		display: flex;
		align-items: center;
	}

	.icons {
		width: 80px;
		height: 30px;
		display: flex;
		align-items: center;
		justify-content: center;
		border: 1px solid #a0cfff;
		color: #46a2ff;
		margin-right: 10px;
		border-radius: 7px;
		background-color: #ecf5ff;

		i {
			color: #1890ff;
			font-size: 14px;
			margin-right: 5px;
		}
	}
}

.asd {
	width: 300px;
	height: 33px;
	border-radius: 5px;
	border: 1px dotted #ccc;
	margin-left: 20px;
	display: flex;
	align-items: center;

	p {
		color: #606266;
		margin-left: 5px;
	}

	:deep(.el-input__wrapper) {
		border: none;
		box-shadow: none !important;
	}

	:deep(.el-date-editor.el-input) {
		width: 200px !important;
	}

	:deep(.el-select__wrapper) {
		border: none;
		box-shadow: none !important;
	}
}

:deep(.gantt_layout_cell) {
	border-radius: 7px;
}

:deep(.gantt_tree_indent) {
	opacity: 0;
}

:deep(.gantt_grid_scale .gantt_grid_head_cell) {
	color: #606266;
	font-size: 15px;
	font-weight: 700;
	border-right: 1px solid #ccc !important;
}

:deep(.gantt_scale_cell) {
	color: #454545 !important;
}

:deep(.gantt_grid_data .gantt_cell) {
	border-right: 1px solid #ccc !important;
	padding: 0;
}

:deep(.gantt_task_progress_wrapper) {
	border-radius: 5px;
}

:deep(.gantt_task_line.gantt_project) {
	border-radius: 5px;
	border: none;
}

:deep(.gantt_data_area div) {
	border-radius: 5px;
	// border:none;
}

:deep(.gantt_tree_content) {
	display: flex;
	align-items: center;

	.jindu {
		width: 100%;
		display: flex;
		justify-content: center;
		align-items: center;
		color: #4482e3;
		border-radius: 10px;
	}

	.tasktype {
		width: 100%;
		height: 100%;
		display: flex;
		justify-content: center;
		align-items: center;
	}
}

:deep(.gantt_task_line) {
	border: none;
}

:deep(.gantt_link_point) {
	display: none !important;
}

:deep(.gantt_task_progress) {
	height: 100%;
}

.toppingTask {
	width: 200px;
	height: 200px;
	background-color: #1890ff;
}
</style>    